﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SiemensOPC;
using Opc.Ua;
using Opc.Ua.Client;
using VswService_V7.Config;
using VswService_V7.DataBase.Tables;
using System.Data;
using VswService_V7.Utility;
using VswService_V7.DataBase;

namespace VswService_V7.OPC.DB
{
    public class Bc5AddressDbdata : SubscriptionDbDataBase
    {
        public Bc5AddressDbdata(SimaticOPCClient opc, NodeConfig nodes) : base(opc, nodes)
        {
            _bundleInitialed = false;
            _bundle = new BundlePipeList();
        }

        string _Location = "BC5";

        /// <summary>
        /// bundle 内的pipe 信息
        /// </summary>
        BundlePipeList _bundle;

        /// <summary>
        /// 当前 BC pipe 数量
        /// </summary>
        int _bcPipeCount = 0;

        /// <summary>
        /// 服务器启动时=false,执行一次更新printPipeList 后 =true
        /// </summary>
        bool _bundleInitialed = false;

        /// <summary>
        /// bundle 结束信号
        /// </summary>
        bool _bundle_Complete = false;

        public override void CreateSubscription()
        {
            opcServer.QuickAddMonitorItem(opcNodes.Bc5Address.GrpoupName,
                opcNodes.Bc5Address.PublishTime,
                opcNodes.Bc5Address.SampleTime,
                opcNodes.Bc5Address.GetNodeAddress(),
                opcNodes.Bc5Address.GetNodeDisplayName(),
                SubscriptionHandleBc);
            opcServer.QuickAddMonitorItem(opcNodes.Bc5CurrentPipeAddress.GrpoupName,
                opcNodes.Bc5CurrentPipeAddress.PublishTime,
                opcNodes.Bc5CurrentPipeAddress.SampleTime,
                opcNodes.Bc5CurrentPipeAddress.GetNodeAddress(),
                opcNodes.Bc5CurrentPipeAddress.GetNodeDisplayName(),
                SubscriptionHandleBcCurrent);
            //Task.Run(() => InitialPipeList());
        }

        private void SubscriptionHandleBc(MonitoredItem monitoredItem, MonitoredItemNotificationEventArgs e)
        {
            try
            {
                MonitoredItemNotification notification = e.NotificationValue as MonitoredItemNotification;
                if (notification == null || notification.Value.Value == null)
                    return;
                Console.WriteLine(_Location + "  REQUEST");
                if (monitoredItem.DisplayName == "Print_Request")
                {
                    bool ask;
                    if (bool.TryParse(notification.Value.Value.ToString(), out ask))
                    {
                        if (ask)
                        {
                            //打印钢管信息(只管打印)
                            List<string> pipeFullNameList = _bundle.GetBundleFullPipeNoList();
                            int count = pipeFullNameList.Count;
                            for (int i = 0; i < count; i++)
                            {
                                Console.WriteLine(_Location + " 打印钢管:  " + pipeFullNameList[i]);
                            }

                            opcServer.WriteValue("true", opcNodes.Bc5Address.Print_Finished);
                            Console.WriteLine(_Location + "  printfinished置为true");
                        }
                        else
                        {
                            opcServer.WriteValue("false", opcNodes.Bc5Address.Print_Finished);
                            Console.WriteLine(_Location + "  printfinished置为false");
                        }
                    }
                }

                else if (monitoredItem.DisplayName == "Bundle_Complete")
                {
                    bool ask;
                    if (bool.TryParse(notification.Value.Value.ToString(), out ask))
                        _bundle_Complete = ask;
                }

                else if (monitoredItem.DisplayName == "Clear")
                {
                    bool ask;
                    if (bool.TryParse(notification.Value.Value.ToString(), out ask))
                    {
                        if (ask)
                        {
                            _bundle.Clear();
                            _bcPipeCount = 0;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }

        private void SubscriptionHandleBcCurrent(MonitoredItem monitoredItem, MonitoredItemNotificationEventArgs e)
        {
            try
            {
                MonitoredItemNotification notification = e.NotificationValue as MonitoredItemNotification;
                if (notification == null || notification.Value.Value == null)
                    return;

                if (notification.Value.Value.Equals(null))
                    return;
                switch (monitoredItem.DisplayName)
                {
                    case "Batch_No":
                        {
                            Console.WriteLine(_Location + " new batch: " + notification.Value);
                            _bundle.currentBatchNo = notification.Value.Value.ToString();
                            break;
                        }
                    case "Pipe_No":
                        {
                            Console.WriteLine(_Location + " new pipe: " + notification.Value);
                            _bundle.currentPipeNo = notification.Value.Value.ToString();
                            break;
                        }
                    case "Pipe_Quantity":
                        {
                            Console.WriteLine(_Location + " quantity is:  " + notification.Value);
                            _bcPipeCount = Convert.ToInt32(notification.Value.Value.ToString());
                            if (!_bundleInitialed)
                            {
                                if (_bcPipeCount > 0)
                                    Task.Run(() => InitialPipeList(opcNodes.Bc5HistoryPipeAddress.Batch_No_1, opcNodes.Bc5HistoryPipeAddress.Pipe_No_1, opcNodes.Bc5HistoryPipeAddress.BufferCount));
                                else
                                    _bundleInitialed = true;
                            }
                            else
                            {
                                if (_bcPipeCount > 0)
                                    Task.Run(() => AddPipeList());
                            }
                            break;
                        }
                    default:
                        {
                            break;
                        }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }

        private async Task InitialPipeList(string firstBatchNoAddress, string firstPipeNoAddress, int maxBuff)
        {
            await Task.Delay(500);
            string replaceAddress = "[1]";
            string batchNoAddress = firstBatchNoAddress;
            string pipeNoAddress = firstPipeNoAddress;
            int count = Math.Min(_bcPipeCount, maxBuff);
            List<string> initialBatchNoAddress = new List<string>();
            List<string> initialPipeNoAddress = new List<string>();
            for (int i = 0; i < count; i++)
            {
                string newReplacedAddress = "[" + (i + 1).ToString() + "]";
                //ns=7;s=S7300ET200M station_1.7+U03_KF1011.6T_BC4.NO1.Batch_ID
                //ns=7;s=S7300ET200M station_1.7+U03_KF1011.6T_BC4.NO1.P_ID
                string batch = batchNoAddress.Replace(replaceAddress, newReplacedAddress);
                string pipe = pipeNoAddress.Replace(replaceAddress, newReplacedAddress);
                initialBatchNoAddress.Add(batch);
                initialPipeNoAddress.Add(pipe);
            }
            int pipeCount = Math.Min(initialBatchNoAddress.Count, initialPipeNoAddress.Count);
            _bundle.batchNoList.Clear();
            _bundle.pipeNoList.Clear();
            for (int i = 0; i < pipeCount; i++)
            {
                _bundle.batchNoList.Add(opcServer.ReadNodeValue(initialBatchNoAddress[i]).Value.ToString());
                _bundle.pipeNoList.Add(opcServer.ReadNodeValue(initialPipeNoAddress[i]).Value.ToString());
            }

            _bundle.bundleNumber = DateTime.Now.ToString(Formats.BundleIdFormat);
            _bundle.eventNo = OracleHelper.GetNextEventNo();

            _bundleInitialed = true;
        }

        private async Task AddPipeList()
        {
            await Task.Delay(1000);
            Console.WriteLine(_Location + " handlepipe start record");
            //第一根需要创建bundleNo
            if (_bcPipeCount == 1)
            {
                Console.WriteLine(_Location + " created bundle NO and eventId");
                _bundle.bundleNumber = DateTime.Now.ToString(Formats.BundleIdFormat);
                _bundle.eventNo = OracleHelper.GetNextEventNo();
            }
            else if (_bcPipeCount != _bundle.pipeNoList.Count + 1)
            {
                await InitialPipeList(opcNodes.Bc5HistoryPipeAddress.Batch_No_1, opcNodes.Bc5HistoryPipeAddress.Pipe_No_1, opcNodes.Bc5HistoryPipeAddress.BufferCount);
                return;
            }
            _bundle.batchNoList.Add(_bundle.currentBatchNo);
            _bundle.pipeNoList.Add(_bundle.currentPipeNo);

            try
            {
                PIPE_INFO.UpdatePipeInfoRecord(_bundle.GetCurrentFullPipeNo(), DateTime.Now, _Location);
                var eventNo = OracleHelper.GetNextEventNo();
                BUNDLE_TABLE.InsertPipeToBundle(eventNo, _bundle.bundleNumber, _bundle.GetCurrentFullPipeNo(), _Location);
                Console.WriteLine(_Location + " new pipe come in: " + _bundle.GetCurrentFullPipeNo());
            }
            catch (Exception ex)
            {
                LogHelper.WriteLog("AddPipeList", ex);
            }
        }

    }
}
